// pages/example/sign/sign.js
Page({
  data: {
    canvasName: "handWriting",
    ctx: "",
    canvasWidth: 0,
    canvasHeight: 0,
    transparent: 1,
    // 透明度
    selectColor: "black",
    lineColor: "#1A1A1A",
    // 颜色
    lineSize: 1.5,
    // 笔记倍数
    lineMin: 0.5,
    // 最小笔画半径
    lineMax: 4,
    // 最大笔画半径
    pressure: 1,
    // 默认压力
    smoothness: 60,
    //顺滑度，用60的距离来计算速度
    currentPoint: {},
    currentLine: [],
    // 当前线条
    firstTouch: true,
    // 第一次触发
    radius: 1,
    //画圆的半径
    cutArea: {
      top: 0,
      right: 0,
      bottom: 0,
      left: 0,
    },
    //裁剪区域
    bethelPoint: [],
    //保存所有线条 生成的贝塞尔点；
    lastPoint: 0,
    chirography: [],
    //笔迹
    currentChirography: {},
    //当前笔迹
    linePrack: [], //划线轨迹 , 生成线条的实际点
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad() {
    let _this = this;
    let canvasName = this.data.canvasName;
    let ctx = wx.createCanvasContext(canvasName);
    this.setData({
      ctx: ctx,
    });
    let query = wx.createSelectorQuery();
    wx.nextTick(function () {
      query
        .select(".handCenter")
        .boundingClientRect(function (rect) {
          _this.canvasWidth = rect.width;
          _this.canvasHeight = rect.height;

          /* 将canvas背景设置为 白底，不设置  导出的canvas的背景为透明 */
          _this.setCanvasBg("#fff");
        })
        .exec();
    });
  },
  // 笔迹开始
  uploadScaleStart: function (e) {
    // 定义函数 uploadScaleStart，接收事件对象 e 作为参数
    if (e.type != "touchstart") return false; // 如果事件类型不是 touchstart，则返回 false
    let ctx = this.data.ctx; // 获取当前组件的 canvas 上下文
    ctx.setFillStyle(this.data.lineColor); // 设置线条颜色
    ctx.setGlobalAlpha(this.data.transparent); // 设置线条透明度
    let currentPoint = {
      // 创建当前触摸点的坐标对象
      x: e.touches[0].x, // 获取触摸点的 x 坐标
      y: e.touches[0].y, // 获取触摸点的 y 坐标
    };
    let currentLine = this.data.currentLine; // 获取当前线条的数组
    currentLine.unshift({
      // 在数组开头添加一个新的点
      time: new Date().getTime(), // 记录当前时间
      dis: 0, // 距离设为 0
      x: currentPoint.x, // 记录当前点的 x 坐标
      y: currentPoint.y, // 记录当前点的 y 坐标
    });
    this.data.currentPoint = currentPoint; // 将当前点保存到 data 对象中
    if (this.data.firstTouch) {
      // 如果是第一次触摸
      this.data.cutArea = {
        // 设置裁剪区域
        top: currentPoint.y, // 上边界为当前点的 y 坐标
        right: currentPoint.x, // 右边界为当前点的 x 坐标
        bottom: currentPoint.y, // 下边界为当前点的 y 坐标
        left: currentPoint.x, // 左边界为当前点的 x 坐标
      };
      this.data.firstTouch = false; // 将 firstTouch 标记为 false
    }
    this.pointToLine(currentLine); // 调用 pointToLine 方法，将当前线条传入
  },
  // 笔迹移动
  uploadScaleMove: function uploadScaleMove(e) {
    // 定义函数 uploadScaleMove，接收事件对象 e 作为参数
    if (e.type != "touchmove") return false; // 如果事件类型不是 touchmove，则返回 false
    if (e.cancelable) {
      // 判断事件是否可取消
      // 判断默认行为是否已经被禁用
      if (!e.defaultPrevented) {
        // 如果默认行为未被禁用
        e.preventDefault(); // 阻止默认行为
      }
    }
    let point = {
      // 创建当前触摸点的坐标对象
      x: e.touches[0].x, // 获取触摸点的 x 坐标
      y: e.touches[0].y, // 获取触摸点的 y 坐标
    };

    //测试裁剪
    if (point.y < this.data.cutArea.top) {
      // 如果触摸点的 y 坐标小于裁剪区域的上边界
      this.data.cutArea.top = point.y; // 将裁剪区域的上边界设置为触摸点的 y 坐标
    }
    if (point.y < 0) this.data.cutArea.top = 0; // 如果触摸点的 y 坐标小于 0，则将裁剪区域的上边界设置为 0
    if (point.x > this.data.cutArea.right) {
      // 如果触摸点的 x 坐标大于裁剪区域的右边界
      this.data.cutArea.right = point.x; // 将裁剪区域的右边界设置为触摸点的 x 坐标
    }
    if (this.data.canvasWidth - point.x <= 0) {
      // 如果触摸点距离画布右边界的距离小于等于 0
      this.data.cutArea.right = this.data.canvasWidth; // 将裁剪区域的右边界设置为画布的宽度
    }
    if (point.y > this.data.cutArea.bottom) {
      // 如果触摸点的 y 坐标大于裁剪区域的下边界
      this.data.cutArea.bottom = point.y; // 将裁剪区域的下边界设置为触摸点的 y 坐标
    }
    if (this.data.canvasHeight - point.y <= 0) {
      // 如果触摸点距离画布下边界的距离小于等于 0
      this.data.cutArea.bottom = this.data.canvasHeight; // 将裁剪区域的下边界设置为画布的高度
    }
    if (point.x < this.data.cutArea.left) {
      // 如果触摸点的 x 坐标小于裁剪区域的左边界
      this.data.cutArea.left = point.x; // 将裁剪区域的左边界设置为触摸点的 x 坐标
    }
    if (point.x < 0) this.data.cutArea.left = 0; // 如果触摸点的 x 坐标小于 0，则将裁剪区域的左边界设置为 0
    this.data.lastPoint = this.data.currentPoint; // 将上一个触摸点的坐标保存到 lastPoint 属性中
    this.data.currentPoint = point; // 将当前触摸点的坐标保存到 currentPoint 属性中
    let currentLine = this.data.currentLine; // 获取当前线条的数组
    currentLine.unshift({
      // 在数组开头添加一个新的点
      time: new Date().getTime(), // 记录当前时间
      dis: this.distance(this.data.currentPoint, this.data.lastPoint), // 计算当前点与上一个点之间的距离
      x: point.x, // 记录当前点的 x 坐标
      y: point.y, // 记录当前点的 y 坐标
    });
    this.pointToLine(currentLine); // 调用 pointToLine 方法，将当前线条传入
  },
  // 笔迹结束
  uploadScaleEnd: function uploadScaleEnd(e) {
    // 定义函数 uploadScaleEnd，接收事件对象 e 作为参数
    if (e.type != "touchend") return 0; // 如果事件类型不是 touchend，则返回 0
    let point = {
      // 创建当前触摸点的坐标对象
      x: e.changedTouches[0].x, // 获取触摸点的 x 坐标
      y: e.changedTouches[0].y, // 获取触摸点的 y 坐标
    };
    this.data.lastPoint = this.data.currentPoint; // 将上一个触摸点的坐标保存到 lastPoint 属性中
    this.data.currentPoint = point; // 将当前触摸点的坐标保存到 currentPoint 属性中
    let currentLine = this.data.currentLine; // 获取当前线条的数组
    currentLine.unshift({
      // 在数组开头添加一个新的点
      time: new Date().getTime(), // 记录当前时间
      dis: this.distance(this.data.currentPoint, this.data.lastPoint), // 计算当前点与上一个点之间的距离
      x: point.x, // 记录当前点的 x 坐标
      y: point.y, // 记录当前点的 y 坐标
    });
    if (currentLine.length > 2) {
      // 如果当前线条的长度大于 2
      let info =
        (currentLine[0].time - currentLine[currentLine.length - 1].time) /
        currentLine.length; // 计算当前线条的平均速度
      //$("#info").text(info.toFixed(2));
    }
    //一笔结束，保存笔迹的坐标点，清空，当前笔迹
    //增加判断是否在手写区域；
    this.pointToLine(currentLine); // 调用 pointToLine 方法，将当前线条传入
    let currentChirography = {
      // 创建当前笔迹的对象
      lineSize: this.data.lineSize, // 记录当前笔迹的线条大小
      lineColor: this.data.lineColor, // 记录当前笔迹的线条颜色
    };
    let chirography = this.data.chirography; // 获取所有笔迹的数组
    chirography.unshift(currentChirography); // 在数组开头添加当前笔迹的对象
    this.data.chirography = chirography; // 将所有笔迹的数组保存到 data 对象中
    let linePrack = this.data.linePrack; // 获取所有线条的数组
    linePrack.unshift(this.data.currentLine); // 在数组开头添加当前线条的数组
    this.data.linePrack = linePrack; // 将所有线条的数组保存到 data 对象中
    this.data.currentLine = []; // 清空当前线条的数组
  },
  retDraw: function retDraw() {
    // 定义函数 retDraw
    this.data.ctx.clearRect(0, 0, 700, 730); // 清除画布上的内容
    this.data.ctx.draw(); // 将画布内容绘制出来

    //设置canvas背景
    this.setCanvasBg("#fff"); // 调用 setCanvasBg 方法，将画布背景设置为白色
  },
  //画两点之间的线条；参数为:line，会绘制最近的开始的两个点；
  pointToLine: function (line) {
    this.calcBethelLine(line);
    return;
  },
  //计算插值的方式；
  calcBethelLine: function calcBethelLine(line) {
    // 定义函数 calcBethelLine，接收线条数组 line 作为参数
    if (line.length <= 1) {
      // 如果线条数组长度小于等于 1
      line[0].r = this.data.radius; // 将线条数组的第一个元素的半径设置为 data 对象中的半径属性
      return; // 返回
    }
    let x0, // 定义变量 x0
      x1, // 定义变量 x1
      x2, // 定义变量 x2
      y0, // 定义变量 y0
      y1, // 定义变量 y1
      y2, // 定义变量 y2
      r0, // 定义变量 r0
      r1, // 定义变量 r1
      r2, // 定义变量 r2
      len, // 定义变量 len
      lastRadius, // 定义变量 lastRadius
      dis = 0, // 定义变量 dis，初始值为 0
      time = 0, // 定义变量 time，初始值为 0
      curveValue = 0.5; // 定义变量 curveValue，初始值为 0.5
    if (line.length <= 2) {
      // 如果线条数组长度小于等于 2
      x0 = line[1].x; // 将变量 x0 设置为线条数组的第二个元素的 x 坐标
      y0 = line[1].y; // 将变量 y0 设置为线条数组的第二个元素的 y 坐标
      x2 = line[1].x + (line[0].x - line[1].x) * curveValue; // 将变量 x2 设置为线条数组的第二个元素的 x 坐标加上第一个元素的 x 坐标与第二个元素的 x 坐标之差乘以 curveValue
      y2 = line[1].y + (line[0].y - line[1].y) * curveValue; // 将变量 y2 设置为线条数组的第二个元素的 y 坐标加上第一个元素的 y 坐标与第二个元素的 y 坐标之差乘以 curveValue
      //x2 = line[1].x;
      //y2 = line[1].y;
      x1 = x0 + (x2 - x0) * curveValue; // 将变量 x1 设置为变量 x0 加上变量 x2 减去变量 x0 的差乘以 curveValue
      y1 = y0 + (y2 - y0) * curveValue; // 将变量 y1 设置为变量 y0 加上变量 y2 减去变量 y0 的差乘以 curveValue
    } else {
      // 如果线条数组长度大于 2
      x0 = line[2].x + (line[1].x - line[2].x) * curveValue; // 将变量 x0 设置为线条数组的第三个元素的 x 坐标加上第二个元素的 x 坐标与第三个元素的 x 坐标之差乘以 curveValue
      y0 = line[2].y + (line[1].y - line[2].y) * curveValue; // 将变量 y0 设置为线条数组的第三个元素的 y 坐标加上第二个元素的 y 坐标与第三个元素的 y 坐标之差乘以 curveValue
      x1 = line[1].x; // 将变量 x1 设置为线条数组的第二个元素的 x 坐标
      y1 = line[1].y; // 将变量 y1 设置为线条数组的第二个元素的 y 坐标
      x2 = x1 + (line[0].x - x1) * curveValue; // 将变量 x2 设置为变量 x1 加上第一个元素的 x 坐标与变量 x1 的差乘以 curveValue
      y2 = y1 + (line[0].y - y1) * curveValue; // 将变量 y2 设置为变量 y1 加上第一个元素的 y 坐标与变量 y1 的差乘以 curveValue
    }
    //从计算公式看，三个点分别是(x0,y0),(x1,y1),(x2,y2) ；(x1,y1)这个是控制点，控制点不会落在曲线上；实际上，这个点还会手写获取的实际点，却落在曲线上
    len = this.distance(
      // 将变量 len 设置为 distance 方法的返回值，该方法接收两个坐标对象作为参数
      {
        x: x2, // 坐标对象的 x 属性为变量 x2
        y: y2, // 坐标对象的 y 属性为变量 y2
      },
      {
        x: x0, // 坐标对象的 x 属性为变量 x0
        y: y0, // 坐标对象的 y 属性为变量 y0
      }
    );
    lastRadius = this.data.radius; // 将变量 lastRadius 设置为 data 对象中的半径属性
    for (let _n = 0; _n < line.length - 1; _n++) {
      // 循环遍历线条数组
      dis += line[_n].dis; // 将变量 dis 加上当前元素的 dis 属性
      time += line[_n].time - line[_n + 1].time; // 将变量 time 加上当前元素的 time 属性减去下一个元素的 time 属性
      if (dis > this.data.smoothness) break; // 如果变量 dis 大于 data 对象中的 smoothness 属性，则跳出循环
    }
    this.radius = // 将 radius 属性设置为以下表达式的值
      Math.min(
        (time / len) * this.data.pressure + this.data.lineMin, // (time / len) * pressure + lineMin
        this.data.lineMax // lineMax
      ) * this.data.lineSize; // 乘以 lineSize
    line[0].r = this.data.radius; // 将线条数组的第一个元素的半径设置为 radius 属性
    //计算笔迹半径；
    if (line.length <= 2) {
      // 如果线条数组长度小于等于 2
      r0 = (lastRadius + this.data.radius) / 2; // 将变量 r0 设置为 lastRadius 和 radius 的平均值
      r1 = r0; // 将变量 r1 设置为变量 r0
      r2 = r1; // 将变量 r2 设置为变量 r1
      //return;
    } else {
      // 如果线条数组长度大于 2
      r0 = (line[2].r + line[1].r) / 2; // 将变量 r0 设置为线条数组的第三个元素的半径和第二个元素的半径的平均值
      r1 = line[1].r; // 将变量 r1 设置为线条数组的第二个元素的半径
      r2 = (line[1].r + line[0].r) / 2; // 将变量 r2 设置为线条数组的第二个元素的半径和第一个元素的半径的平均值
    }
    let n = 5; // 定义变量 n，初始值为 5
    let point = []; // 定义变量 point，初始值为空数组
    for (let i = 0; i < n; i++) {
      // 循环遍历变量 n
      let t = i / (n - 1); // 将变量 t 设置为 i 除以 n 减去 1
      let x = (1 - t) * (1 - t) * x0 + 2 * t * (1 - t) * x1 + t * t * x2; // 将变量 x 设置为以下表达式的值
      let y = (1 - t) * (1 - t) * y0 + 2 * t * (1 - t) * y1 + t * t * y2; // 将变量 y 设置为以下表达式的值
      let r = lastRadius + ((this.data.radius - lastRadius) / n) * i; // 将变量 r 设置为以下表达式的值
      point.push({
        // 将一个新的坐标对象添加到 point 数组中
        x: x, // 坐标对象的 x 属性为变量 x
        y: y, // 坐标对象的 y 属性为变量 y
        r: r, // 坐标对象的 r 属性为变量 r
      });
      if (point.length == 3) {
        // 如果 point 数组的长度等于 3
        let a = this.ctaCalc(
          // 将变量 a 设置为 ctaCalc 方法的返回值，该方法接收 9 个参数
          point[0].x, // 第一个参数为 point 数组的第一个元素的 x 坐标
          point[0].y, // 第二个参数为 point 数组的第一个元素的 y 坐标
          point[0].r, // 第三个参数为 point 数组的第一个元素的半径
          point[1].x, // 第四个参数为 point 数组的第二个元素的 x 坐标
          point[1].y, // 第五个参数为 point 数组的第二个元素的 y 坐标
          point[1].r, // 第六个参数为 point 数组的第二个元素的半径
          point[2].x, // 第七个参数为 point 数组的第三个元素的 x 坐标
          point[2].y, // 第八个参数为 point 数组的第三个元素的 y 坐标
          point[2].r // 第九个参数为 point 数组的第三个元素的半径
        );
        a[0].color = this.data.lineColor; // 将变量 a 的第一个元素的 color 属性设置为 data 对象中的线条颜色属性
        // let bethelPoint = this.bethelPoint;
        // bethelPoint = bethelPoint.push(a);
        this.bethelDraw(a, 1); // 调用 bethelDraw 方法，将变量 a 和 1 作为参数
        point = [
          // 将 point 数组重置为只包含一个元素的数组
          {
            x: x, // 坐标对象的 x 属性为变量 x
            y: y, // 坐标对象的 y 属性为变量 y
            r: r, // 坐标对象的 r 属性为变量 r
          },
        ];
      }
    }
    this.data.currentLine = line; // 将线条数组保存到 data 对象的 currentLine 属性中
  },
  //求两点之间距离
  distance: function (a, b) {
    let x = b.x - a.x;
    let y = b.y - a.y;
    return Math.sqrt(x * x + y * y);
  },
  ctaCalc: function (x0, y0, r0, x1, y1, r1, x2, y2, r2) {
    // 定义函数 ctaCalc，接收 9 个参数
    let a = [], // 创建空数组 a
      vx01, // 定义变量 vx01
      vy01, // 定义变量 vy01
      norm, // 定义变量 norm
      n_x0, // 定义变量 n_x0
      n_y0, // 定义变量 n_y0
      vx21, // 定义变量 vx21
      vy21, // 定义变量 vy21
      n_x2, // 定义变量 n_x2
      n_y2; // 定义变量 n_y2
    vx01 = x1 - x0; // 计算向量 x1-x0 的 x 坐标差值
    vy01 = y1 - y0; // 计算向量 x1-x0 的 y 坐标差值
    norm = Math.sqrt(vx01 * vx01 + vy01 * vy01 + 0.0001) * 2; // 计算向量 x1-x0 的长度
    vx01 = (vx01 / norm) * r0; // 计算向量 x1-x0 的单位向量，并乘以 r0 得到新的向量
    vy01 = (vy01 / norm) * r0; // 计算向量 x1-x0 的单位向量，并乘以 r0 得到新的向量
    n_x0 = vy01; // 计算向量 x1-x0 的法向量
    n_y0 = -vx01; // 计算向量 x1-x0 的法向量
    vx21 = x1 - x2; // 计算向量 x2-x1 的 x 坐标差值
    vy21 = y1 - y2; // 计算向量 x2-x1 的 y 坐标差值
    norm = Math.sqrt(vx21 * vx21 + vy21 * vy21 + 0.0001) * 2; // 计算向量 x2-x1 的长度
    vx21 = (vx21 / norm) * r2; // 计算向量 x2-x1 的单位向量，并乘以 r2 得到新的向量
    vy21 = (vy21 / norm) * r2; // 计算向量 x2-x1 的单位向量，并乘以 r2 得到新的向量
    n_x2 = -vy21; // 计算向量 x2-x1 的法向量
    n_y2 = vx21; // 计算向量 x2-x1 的法向量
    a.push({
      // 在数组 a 中添加一个对象
      mx: x0 + n_x0, // 计算起始点的坐标
      my: y0 + n_y0, // 计算起始点的坐标
      color: "#1A1A1A", // 设置颜色
    });
    a.push({
      // 在数组 a 中添加一个对象
      c1x: x1 + n_x0, // 计算控制点 1 的坐标
      c1y: y1 + n_y0, // 计算控制点 1 的坐标
      c2x: x1 + n_x2, // 计算控制点 2 的坐标
      c2y: y1 + n_y2, // 计算控制点 2 的坐标
      ex: x2 + n_x2, // 计算结束点的坐标
      ey: y2 + n_y2, // 计算结束点的坐标
    });
    a.push({
      // 在数组 a 中添加一个对象
      c1x: x2 + n_x2 - vx21, // 计算控制点 1 的坐标
      c1y: y2 + n_y2 - vy21, // 计算控制点 1 的坐标
      c2x: x2 - n_x2 - vx21, // 计算控制点 2 的坐标
      c2y: y2 - n_y2 - vy21, // 计算控制点 2 的坐标
      ex: x2 - n_x2, // 计算结束点的坐标
      ey: y2 - n_y2, // 计算结束点的坐标
    });
    a.push({
      // 在数组 a 中添加一个对象
      c1x: x1 - n_x2, // 计算控制点 1 的坐标
      c1y: y1 - n_y2, // 计算控制点 1 的坐标
      c2x: x1 - n_x0, // 计算控制点 2 的坐标
      c2y: y1 - n_y0, // 计算控制点 2 的坐标
      ex: x0 - n_x0, // 计算结束点的坐标
      ey: y0 - n_y0, // 计算结束点的坐标
    });
    a.push({
      // 在数组 a 中添加一个对象
      c1x: x0 - n_x0 - vx01, // 计算控制点 1 的坐标
      c1y: y0 - n_y0 - vy01, // 计算控制点 1 的坐标
      c2x: x0 + n_x0 - vx01, // 计算控制点 2 的坐标
      c2y: y0 + n_y0 - vy01, // 计算控制点 2 的坐标
      ex: x0 + n_x0, // 计算结束点的坐标
      ey: y0 + n_y0, // 计算结束点的坐标
    });
    a[0].mx = a[0].mx.toFixed(1); // 将起始点的 x 坐标保留一位小数
    a[0].mx = parseFloat(a[0].mx); // 将起始点的 x 坐标转换为浮点数
    a[0].my = a[0].my.toFixed(1); // 将起始点的 y 坐标保留一位小数
    a[0].my = parseFloat(a[0].my); // 将起始点的 y 坐标转换为浮点数
    for (let i = 1; i < a.length; i++) {
      // 遍历数组 a 中的对象
      a[i].c1x = a[i].c1x.toFixed(1); // 将控制点 1 的 x 坐标保留一位小数
      a[i].c1x = parseFloat(a[i].c1x); // 将控制点 1 的 x 坐标转换为浮点数
      a[i].c1y = a[i].c1y.toFixed(1); // 将控制点 1 的 y 坐标保留一位小数
      a[i].c1y = parseFloat(a[i].c1y); // 将控制点 1 的 y 坐标转换为浮点数
      a[i].c2x = a[i].c2x.toFixed(1); // 将控制点 2 的 x 坐标保留一位小数
      a[i].c2x = parseFloat(a[i].c2x); // 将控制点 2 的 x 坐标转换为浮点数
      a[i].c2y = a[i].c2y.toFixed(1); // 将控制点 2 的 y 坐标保留一位小数
      a[i].c2y = parseFloat(a[i].c2y); // 将控制点 2 的 y 坐标转换为浮点数
      a[i].ex = a[i].ex.toFixed(1); // 将结束点的 x 坐标保留一位小数
      a[i].ex = parseFloat(a[i].ex); // 将结束点的 x 坐标转换为浮点数
      a[i].ey = a[i].ey.toFixed(1); // 将结束点的 y 坐标保留一位小数
      a[i].ey = parseFloat(a[i].ey); // 将结束点的 y 坐标转换为浮点数
    }
    return a; // 返回数组 a
  },
  bethelDraw: function bethelDraw(point, is_fill, color) {
    // 定义函数 bethelDraw，接收 3 个参数
    let ctx = this.data.ctx; // 获取画布上下文
    ctx.beginPath(); // 开始绘制路径
    ctx.moveTo(point[0].mx, point[0].my); // 将路径移动到起始点
    if (undefined != color) {
      // 如果颜色参数不为空
      ctx.setFillStyle(color); // 设置填充颜色
      ctx.setStrokeStyle(color); // 设置描边颜色
    } else {
      // 如果颜色参数为空
      ctx.setFillStyle(point[0].color); // 设置填充颜色为起始点的颜色
      ctx.setStrokeStyle(point[0].color); // 设置描边颜色为起始点的颜色
    }
    for (let i = 1; i < point.length; i++) {
      // 遍历数组中的对象
      ctx.bezierCurveTo(
        // 绘制贝塞尔曲线
        point[i].c1x, // 控制点 1 的 x 坐标
        point[i].c1y, // 控制点 1 的 y 坐标
        point[i].c2x, // 控制点 2 的 x 坐标
        point[i].c2y, // 控制点 2 的 y 坐标
        point[i].ex, // 结束点的 x 坐标
        point[i].ey // 结束点的 y 坐标
      );
    }
    ctx.stroke(); // 绘制描边
    if (undefined != is_fill) {
      // 如果填充参数不为空
      ctx.fill(); // 填充图形
    }

    ctx.draw(true); // 将绘制内容绘制到画布上
  },
  selectColorEvent: function (e) {
    let str = e.currentTarget.dataset.colorWord;
    let color = e.currentTarget.dataset.color;
    this.data.selectColor = str;
    this.data.lineColor = color;
  },
  //将Canvas内容转成 临时图片 --> cb 为回调函数 形参 tempImgPath 为 生成的图片临时路径
  canvasToImg: function canvasToImg(cb) {
    //这种写法移动端 出不来
    this.data.ctx.draw(true, function () {
      wx.canvasToTempFilePath({
        canvasId: "handWriting",
        fileType: "png",
        quality: 1,
        //图片质量
        success: function success(res) {
          // console.log(res.tempFilePath, 'canvas生成图片地址');

          wx.showToast({
            title: "执行了吗？",
          });
          cb(res.tempFilePath);
        },
      });
    });
  },
  //完成
  subCanvas: function subCanvas() {
    this.data.ctx.draw(true, function () {
      wx.canvasToTempFilePath({
        canvasId: "handWriting",
        fileType: "png",
        quality: 1,
        //图片质量
        success: function success(res) {
          // console.log(res.tempFilePath, 'canvas生成图片地址');
          wx.showToast({
            title: "以保存",
          });
          //保存到系统相册
          wx.saveImageToPhotosAlbum({
            filePath: res.tempFilePath,
            success: function success(res) {
              wx.showToast({
                title: "已成功保存到相册",
                duration: 2000,
              });
            },
          });
        },
      });
    });
  },
  //保存到相册
  saveCanvasAsImg: function saveCanvasAsImg() {
    /*
    this.canvasToImg( tempImgPath=>{
      // console.log(tempImgPath, '临时路径');
      wx.saveImageToPhotosAlbum({
        filePath: tempImgPath,
        success(res) {
          wx.showToast({
            title: '已保存到相册',
            duration: 2000
          });
        }
      })
    } );
    */

    wx.canvasToTempFilePath({
      canvasId: "handWriting",
      fileType: "png",
      quality: 1,
      //图片质量
      success: function success(res) {
        // console.log(res.tempFilePath, 'canvas生成图片地址');
        wx.saveImageToPhotosAlbum({
          filePath: res.tempFilePath,
          success: function success(res) {
            wx.showToast({
              title: "已保存到相册",
              duration: 2000,
            });
          },
        });
      },
    });
  },
  //预览
  previewCanvasImg: function previewCanvasImg() {
    wx.canvasToTempFilePath({
      canvasId: "handWriting",
      fileType: "jpg",
      quality: 1,
      //图片质量
      success: function success(res) {
        // console.log(res.tempFilePath, 'canvas生成图片地址');

        wx.previewImage({
          urls: [res.tempFilePath], //预览图片 数组
        });
      },
    });

    /*	//移动端出不来  ^~^！！
        this.canvasToImg( tempImgPath=>{
          wx.previewImage({
            urls: [tempImgPath], //预览图片 数组
          })
        } );
    */
  },
  //上传
  uploadCanvasImg: function uploadCanvasImg() {
    wx.canvasToTempFilePath({
      canvasId: "handWriting",
      fileType: "png",
      quality: 1,
      //图片质量
      success: function success(res) {
        console.table(res, "canvas生成图片地址");

        //上传
        // wx.uploadFile({
        //   url: '',
        //   filePath: res.tempFilePath,
        //   name: 'file_signature',
        //   formData: {
        //     user: 'test'
        //   },
        //   success: function success(res) {
        //     let data = res.data;
        //     // do something
        //   }
        // });
      },
    });
  },
  //设置canvas背景色  不设置  导出的canvas的背景为透明
  //@params：字符串  color
  setCanvasBg: function (color) {
    /* 将canvas背景设置为 白底，不设置  导出的canvas的背景为透明 */
    //rect() 参数说明  矩形路径左上角的横坐标，左上角的纵坐标, 矩形路径的宽度, 矩形路径的高度
    //这里是 canvasHeight - 4 是因为下边盖住边框了，所以手动减了写
    this.data.ctx.rect(0, 0, this.data.canvasWidth, this.data.canvasHeight - 4);
    // ctx.setFillStyle('red')
    this.data.ctx.setFillStyle(color);
    this.data.ctx.fill(); //设置填充
    this.data.ctx.draw(); //开画
  },
});
